/**
  ******************************************************************************
  * @file    NORMAD_DRIVER.c
  * @author  Feirui_Joe
  * @version V0.1
  * @date    07/26/2010
  * @brief   ACAD Handling
  ******************************************************************************
  * @copy
  *
  * <h2><center>&copy; COPYRIGHT 2010 Feirui</center></h2>
  */ 



/**
  * @brief  INCLUDE FILES.
  */
#ifndef	NORMAD_DRIVER_GLOBALS
#define	NORMAD_DRIVER_GLOBALS
#include <includes.h>


/************************************/
/*    Initial ADC3 Measure */
/************************************/

static void RCC_ADC3MeasureCfg  (void);
static void GPIO_ADCMeasureCfg (void);
static void Caliba_ADC3hardware (void);
static void Reset_Cfg1DMA_ADC(void);

/* Initial ADC Measure Config */
void ADCMeasureCfg1_Init  (void)
{
  /* System Clocks Configuration */
  RCC_ADC3MeasureCfg();
  
  /* Configure the GPIO ports */
  GPIO_ADCMeasureCfg();
  
  /* Initial ADC&&DMA config */
  Init_DMA_ADCConfig1();
  
  /* ADC calibaration */
  Caliba_ADC3hardware();
}

/**
  * @brief  Configures RCC clock for ADC
  * @param  None
  * @retval None
  */
static void RCC_ADC3MeasureCfg(void)
{
	uint32_t RCC_APBxPeriph_GPIOx;
	uint8_t  i;
  
  /* Set ADCCLK */
  RCC_ADCCLKConfig(SYSADCCLK_FREQ);
  
  /* Enable DMA clock */
  RCC_AHBPeriphClockCmd(Cfg1ADCDMA_RCCPeriph, ENABLE);
  
  /* Enable ADC3 and GPIOx clock */
  for(i=0,RCC_APBxPeriph_GPIOx=0;i<NormADCPortCfgNumber;i++)
    RCC_APBxPeriph_GPIOx|=NormADCPortCfgTbl[i].RCC_APB2Periph;
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3|RCC_APBxPeriph_GPIOx, ENABLE);
}


/**
  * @brief  Configures GPIO
  * @param  None
  * @retval None
  */
static void GPIO_ADCMeasureCfg(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  uint8_t i;
  
  /* Configuration Port for ADC pin */
  for(i=0;i<NormADCPortCfgNumber;i++)
  {
    GPIO_InitStructure.GPIO_Pin   = NormADCPortCfgTbl[i].GPIO_Pin;
    GPIO_InitStructure.GPIO_Speed = NormADCPortCfgTbl[i].GPIO_Speed;
    GPIO_InitStructure.GPIO_Mode  = NormADCPortCfgTbl[i].GPIO_Mode;
    GPIO_Init(NormADCPortCfgTbl[i].GPIOx, &GPIO_InitStructure);
  }
}


/**
  * @brief  Reset ADC && DMA
  * @param  None
  * @retval None
  */
static void Reset_Cfg1DMA_ADC(void)
{
	/* Disable ADC3 */
  ADC_Cmd(ADC3, DISABLE);
	
  /* Disable ADC3 external trigger conversion */
  ADC_ExternalTrigConvCmd(ADC3, DISABLE);
  /* Disable ADC3 DMA */
  ADC_DMACmd(ADC3, DISABLE);
  /* Disable DMAx Channelx */
  DMA_Cmd(Cfg1ADCDMA_Channel, DISABLE);
  
	/* Disable the CCx Interrupt Request */
  DMA_ITConfig(Cfg1ADCDMA_Channel,Cfg1ADCDMA_Channel_IT, DISABLE);
	/* Clear DMA interrupt pending bit */
	DMA_ClearITPendingBit(Cfg1ADCDMA_IT_Mode);
	/* Clear DMA Event Flag */
	DMA_ClearFlag(Cfg1ADCDMA_FLAG_Mode);
}


/**
  * @brief  Initial ADC && DMA
  * @param  None
  * @retval None
  */
void Init_DMA_ADCConfig1(void)
{
  DMA_InitTypeDef DMA_InitStructure;
  ADC_InitTypeDef ADC_InitStructure;
  uint8_t i;
  
  /*Reset ADC && DMA*/
  Reset_Cfg1DMA_ADC();  
  
  /* DMAx channelx configuration ----------------------------------------------*/
  DMA_InitStructure.DMA_PeripheralBaseAddr = Cfg1ADCDMA_PeripheralBaseAddr;
  DMA_InitStructure.DMA_MemoryBaseAddr     = Cfg1ADCDMA_MemoryBaseAddr    ;
  DMA_InitStructure.DMA_DIR                = Cfg1ADCDMA_DIR               ;
  DMA_InitStructure.DMA_BufferSize         = Cfg1ADCDMA_BufferSize        ;
  DMA_InitStructure.DMA_PeripheralInc      = Cfg1ADCDMA_PeripheralInc     ;
  DMA_InitStructure.DMA_MemoryInc          = Cfg1ADCDMA_MemoryInc         ;
  DMA_InitStructure.DMA_PeripheralDataSize = Cfg1ADCDMA_PeripheralDataSize;
  DMA_InitStructure.DMA_MemoryDataSize     = Cfg1ADCDMA_MemoryDataSize    ;
  DMA_InitStructure.DMA_Mode               = Cfg1ADCDMA_Mode              ;
  DMA_InitStructure.DMA_Priority           = Cfg1ADCDMA_Priority          ;
  DMA_InitStructure.DMA_M2M                = Cfg1ADCDMA_M2M               ;
  DMA_Init(Cfg1ADCDMA_Channel, &DMA_InitStructure);
  /* Enable DMAx Channelx */
  DMA_Cmd(Cfg1ADCDMA_Channel, ENABLE);
  
  
  /* ADC3 configuration ------------------------------------------------------*/
  ADC_InitStructure.ADC_Mode               = Cfg1ADC3_Mode              ;
  ADC_InitStructure.ADC_ScanConvMode       = Cfg1ADC3_ScanConvMode      ;
  ADC_InitStructure.ADC_ContinuousConvMode = Cfg1ADC3_ContinuousConvMode;
  ADC_InitStructure.ADC_ExternalTrigConv   = Cfg1ADC3_ExternalTrigConv  ;
  ADC_InitStructure.ADC_DataAlign          = Cfg1ADC3_DataAlign         ;
  ADC_InitStructure.ADC_NbrOfChannel       = Cfg1ADC3_NbrOfChannel      ;
  ADC_Init(ADC3, &ADC_InitStructure);
  /* ADC3 regular channels configuration */
  for(i=0;i<Cfg1ADC_RegularNumber;i++)
    ADC_RegularChannelConfig(ADC3,NormADCRegularCfg1Tbl[i].ADC_Channel,NormADCRegularCfg1Tbl[i].Rank,NormADCRegularCfg1Tbl[i].ADC_SampleTime);
  /* Enable ADC3 DMA */
  ADC_DMACmd(ADC3, ENABLE);
}



/**
  * @brief  ADC calibaration
  * @param  None
  * @retval None
  */
static void Caliba_ADC3hardware(void)
{
  /* Enable ADC3 */
  ADC_Cmd(ADC3, ENABLE);
  
  /* Enable ADC3 reset calibaration register */   
  ADC_ResetCalibration(ADC3);
  /* Check the end of ADC3 reset calibration register */
  while(ADC_GetResetCalibrationStatus(ADC3));
  
  /* Start ADC3 calibaration */
  ADC_StartCalibration(ADC3);
  /* Check the end of ADC3 calibration */
  while(ADC_GetCalibrationStatus(ADC3));
  
  /* Disable ADC3 */
  ADC_Cmd(ADC3, DISABLE);
}




/*$PAGE*/#endif	/*	NORMAD_DRIVER_GLOBALS	*/
